package net.goutalk.glcs.module.liteflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import net.goutalk.glcs.common.exception.MyException;
import net.goutalk.glcs.module.liteflow.dto.AddChainDto;
import net.goutalk.glcs.module.liteflow.dto.ExecuteFlowDto;
import net.goutalk.glcs.module.liteflow.dto.UpdateChainDto;
import net.goutalk.glcs.module.liteflow.entity.LiteflowChain;
import net.goutalk.glcs.module.liteflow.mapper.LiteflowChainMapper;
import net.goutalk.glcs.module.liteflow.service.ILiteflowChainService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.LiteflowResponse;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 规则表 服务实现类
 * </p>
 *
 * @author tanyujie
 * @since 2023-04-06
 */
@Service
@AllArgsConstructor
public class LiteflowChainServiceImpl extends ServiceImpl<LiteflowChainMapper, LiteflowChain> implements ILiteflowChainService {

    private final LiteflowChainMapper chainMapper;

    private final FlowExecutor flowExecutor;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addChain(AddChainDto dto) {
        if (!LiteFlowChainELBuilder.validate(dto.getElData())) {
            throw new MyException("规则编写错误！");
        }
        LiteflowChain liteflowChain = BeanUtil.toBean(dto, LiteflowChain.class);
        liteflowChain.setCreateTime(LocalDateTime.now());
        chainMapper.insert(liteflowChain);

        LiteFlowChainELBuilder.createChain().setChainId(dto.getChainName()).setEL(dto.getElData()).build();
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateChain(UpdateChainDto dto) {
        if (!LiteFlowChainELBuilder.validate(dto.getElData())) {
            throw new MyException("规则编写错误！");
        }
        LiteflowChain liteflowChain = BeanUtil.toBean(dto, LiteflowChain.class);

        chainMapper.updateById(liteflowChain);
        FlowBus.removeChain(dto.getChainName());
        LiteFlowChainELBuilder.createChain().setChainId(dto.getChainName()).setEL(dto.getElData()).build();
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteChain(List<Long> ids) {

        LambdaQueryWrapper<LiteflowChain> select = Wrappers.lambdaQuery(LiteflowChain.class).in(LiteflowChain::getId, ids).select(LiteflowChain::getChainName);
        List<LiteflowChain> liteflowChains = chainMapper.selectList(select);
        String[] names = liteflowChains.stream().map(LiteflowChain::getChainName).toArray(String[]::new);

        chainMapper.deleteBatchIds(ids);

        FlowBus.removeChain(names);
        return true;
    }

    @Override
    public boolean execute(ExecuteFlowDto dto) {

        if(StrUtil.isNotBlank(dto.getChainName())){
            LiteflowResponse liteflowResponse = flowExecutor.execute2Resp(dto.getChainName(), dto.getParams());
            return liteflowResponse.isSuccess();
        }
        else {
            LiteflowChain liteflowChain = chainMapper.selectById(dto.getId());
            LiteflowResponse liteflowResponse = flowExecutor.execute2Resp(liteflowChain.getChainName(), dto.getParams());
            return liteflowResponse.isSuccess();
        }

    }
}
